home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 1.iso
/
ARGONET
/
PD
/
GRAPHICS
/
GIF2RPC.SPK
/
source
/
s
/
map8_quick
< prev
Wrap
Text File
|
1996-01-11
|
5KB
|
151 lines
; map8_quick.s
; MACHINE: RISC OS
; LANGUAGE: OBJASM assembler
; AUTHOR: Cy Booker, cy@cheepnis.demon.co.uk
; LICENSE: FreeWare, Copyright (c) Cy Booker 1995
; PURPOSE: Given an arbitary 48-bit colour, what is the closest 8-bit colour number?
; assuming the default 256 colour palette
GET OS:Hdr.os
;
; in middle we have |intensity-difference| <-- 0x3fff
; so |i|^2 <= 0xfff8001
; and so |d|^2 <= 3.|i|^2 <= 0x2ffe8003
; so total scale must be < 2^32/(|d|^2) , ie < ~5
; but this does not leave enough accuracy really, so we shift by a bit
;
; the weights we want are:
; Red * 0.212671 *358 ~= 76 /128 ~= 0x0.98
; Green * 0.715160 *358 ~= 256 /128 ~= 0x2.00
; Blue * 0.072169 *358 ~= 26 /128 ~= 0x0.34
;
; note we will use the *358 because it makes the inline multiplies very quick
; even though we have to `divide' by 128 (eg 0x2ffe8003 * 358 / 128 < 2^32
;
EXPORT map_scaled_rgb_to_8bpp_colour_number_quick
AREA |ARM$$code|, CODE, READONLY
ROUT
str RN a1
orig_r RN a2
orig_g RN a3
orig_b RN a4
hi_r RN v1
hi_g RN v2
hi_b RN v3
dmin RN v4
tint RN v5
d RN v6
t RN ip
r RN orig_r ; implicit r < g
g RN orig_g ; implicit r < g < b
b RN orig_b ; implicit g < b
best RN str
;
; In R0 -> structure
; R1 = red nominally [0, 0xffff], but clipped as necessary
; R2 = green nominally [0, 0xffff], but clipped as necessary
; R3 = blue nominally [0, 0xffff], but clipped as necessary
; Out R0 <-- palette entry %BGgRbrTt (bits 8-31 are zero)
; structure[0] = error in approximating red intensity
; structure[1] = error in approximating green intensity
; structure[2] = error in approximating blue intensity
;
;
; this algorithm takes as a first approximation the most significant two
; bits of each primary
; this is NOT always the best approximation, and tends to make blacker colours
; the test8bpp program seems to show that we get this wrong 328/1000 times
;
ROUT
map_scaled_rgb_to_8bpp_colour_number_quick
STMFD sp!, {a1, v1-v6, lr} ; store a1 just so have one word of local stack
MOV lr, #0xff00
ORR lr, lr, #0xff
CMP orig_r, #0x10000 ; ensure in range [0, 0xffff]
MOVHS orig_r, #0
MOVGE orig_r, lr
CMP orig_g, #0x10000
MOVHS orig_g, #0
MOVGE orig_g, lr
CMP orig_b, #0x10000
MOVHS orig_b, #0
MOVGE orig_b, lr
;
AND hi_r, orig_r, #&c000 ; two bits of output
ORR hi_r, hi_r, hi_r, LSR #4
ORR hi_r, hi_r, hi_r, LSR #8 ; and this is the real intensity
;
AND hi_g, orig_g, #&c000 ; repeat for green
ORR hi_g, hi_g, hi_g, LSR #4
ORR hi_g, hi_g, hi_g, LSR #8
;
AND hi_b, orig_b, #&c000 ; repeat for blue
ORR hi_b, hi_b, hi_b, LSR #4
ORR hi_b, hi_b, hi_b, LSR #8
;
SUB r, orig_r, hi_r ; r= colour to match tints to
SUB g, orig_g, hi_g
SUB b, orig_b, hi_b
;
MOV tint, #&3300
ORR tint, tint, #&33
MOV dmin, #&ffffffff
0
SUBS t, r, tint ; how different is it?
RSBMI t, t, #0 ; makes multiply faster
MUL lr, t, t
; scale for red ... |r|^2 * (0.212671 * 358 / 128) = 0x0.98
MOVS lr, lr, LSR #1
ADC d, lr, lr, LSR #3 ; |r|^2 * 0x0.9
ADD d, d, lr, LSR #4 ; |r|^2 * 0x0.98
SUBS t, g, tint
RSBMI t, t, #0
MULNE lr, t, t
; scale for green ... |g|^2 * (0.715160 * 358 / 128) = 0x2.00
ADDNE d, d, lr, LSL #1 ; |g|^2 * 0x2
SUBS t, b, tint
RSBMI t, t, #0
MULNE lr, t, t
; scale for blue ... |b|^2 * (0.072169 * 358 / 128) = 0x0.34
ADDNE d, d, lr, LSR #3 ; |b|^2 * 0x0.2
ADDNE d, d, lr, LSR #4 ; |b|^2 * 0x0.3
ADDNE d, d, lr, LSR #6 ; |b|^2 * 0x0.34
CMP d, dmin
MOVLO dmin, d ; .LO. so that chooses lighter tints
MOVLO best, tint ; because most significant bits are 'dark'
SUB tint, tint, #&1100
SUBS tint, tint, #&11
BGE %BT0
SUB r, r, best
SUB g, g, best
SUB b, b, best
LDMFD sp!, {lr}
STMIA lr, {r, g, b} ; store error
AND a1, best, #&03
ORR a1, a1, hi_g, LSL #3 ; a1= %0Gg000Tt
MOVS t, hi_b, LSL #25
ORRCS a1, a1, #&80
ORRMI a1, a1, #&08 ; a1= %BGg0b0Tt
MOVS t, hi_r, LSL #25
ORRCS a1, a1, #&10
ORRMI a1, a1, #&04 ; a1= %BGgRbrTt
AND a1, a1, #&ff ; clear upper garbage
LDMFD sp!, {v1-v6, pc}^
END